#ifndef SERVER_H_
#define SERVER_H_

#include <list>
#include "Connection.h"
#include "ChatRecibirServer.h"
#include "ChatEnviarServer.h"
#include "Mutex.h"
#include "Socket.h"
#include "../modelo/Juego.h"
#include "../yaml/Builder.h"
#include <map>
#include <set>
#include <queue>
#include "Connection.h"

using namespace std;

class Server {
private:
	int port;
	Socket aSocket;
	Socket chatSocket;
	bool working;
	Mutex workingMutex;
	list<Connection*> connections; //Lista de conexiones
	list<Personaje*> personajesInactivos;
	ChatRecibirServer* chatRecibir;
	ChatEnviarServer* chatEnviar;
	Mutex connMutex;
	Juego *juego;
	string nombreEscenario;
	Builder* builderJuego;
	map<string,set<string>* > mapPersonajePosiciones;
	bool gameStart;
	Mutex gameStartMutex;
	pthread_cond_t gameStartCond;
	int puertoChatRecv;
	int puertoChatSend;
	int connectionCount;
	map<string, Connection*>  jugadoresSockets;
	queue<string> mensajesChat;
	bool trabajando;

	bool isWorking();

	void init();

	void startGame();

	void shutdownConnections();
public:
	//Inicializo el socket, el puerto, el path del juego, la cantidad de
	//jugadores y la cantidad de conexiones, y el working en true.
	Server( int port, Juego *juego, Builder* builderJuego, int cc, string nombreEscenario,int puertoChatRecv, int puertoChatSend ) : aSocket(port),chatSocket(puertoChatSend), working(true), cantidadDeJugadores(cc) {this->trabajando = true; this->juego = juego; this->puertoChatRecv = puertoChatRecv;this->puertoChatSend = puertoChatSend; this->builderJuego = builderJuego; this->port=port; connectionCount = 0; this->nombreEscenario = nombreEscenario;	gameStartCond = PTHREAD_COND_INITIALIZER;
};
	virtual ~Server() {};

	void setPort(int port) {this->port = port;};

	void setWorking(bool working);
	void setTrabajando(bool t);
	void serverShutdown();

	list<Connection*> getConnections();

	void run();

	string getNombreEscenario();

	void clearConnections();

	int cantidadDeJugadores;

	list<Personaje*> getPersonajesInactivos();

	Escenario* getEscenario();

	Builder* getBuilderJuego();

	void agregarInactivo(Personaje* personaje);
	void borrarPersonajeInactivo(Personaje* personaje);

	map<string,set<string>* > getMapPersonajePosiciones();
	void setMapPersonajePosiciones(map<string,set<string>* > map);

	void agregarPosicionesVisitadas(string nombrePersonaje, set<string>* posicionesVisitas);
	void recibirMensajeChat(string mensaje);
	queue<string>* getMensajesChat();
	map<string,Connection*> getJugadoresSockets();
	void borrarJugadorDeSockets(string nombre);

	bool getTrabajando();
};

#endif  /* SERVER_H_ */
